package com.pachong.android.framework.web;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.Keep;
import android.util.Log;
import android.webkit.GeolocationPermissions;
import android.webkit.JsResult;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebStorage;
import android.webkit.WebView;
import android.widget.Toast;

import com.pachong.android.baseuicomponent.fragment.BaseFragment;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * CommonWebChromeClient
 * <p/>
 * 兼容js端的各种事件处理
 * 支持文件选择功能，但是api 4.4的不支持，暂无解决办法
 *
 * @Author: PengWeiwei
 * @E-mail: pengveivei@sina.cn
 * @CreateDate: 2016/5/13 14:53
 * @Version: 1.0.0
 */
public class CommonWebChromeClient extends WebChromeClient {
    private BaseFragment mFragment;

    private ValueCallback<Uri> mUploadMsg;
    private ValueCallback<Uri[]> mUploadMsgLollipopPlus;
    private String mCameraPhotoPath;

    public CommonWebChromeClient(BaseFragment fragment) {
        mFragment = fragment;
    }

    //处理javascript中的alert
    public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
        //构建一个Builder来显示网页中的对话框
        AlertDialog.Builder builder = new AlertDialog.Builder(mFragment.getContext());
        builder.setTitle("Alert");
        builder.setMessage(message);
        builder.setPositiveButton(android.R.string.ok,
                new Dialog.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        result.confirm();
                    }
                });
        builder.setCancelable(false);
        builder.create();
        builder.show();
        return true;
    }

    //处理javascript中的confirm
    public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
        AlertDialog.Builder builder = new AlertDialog.Builder(mFragment.getContext());
        builder.setTitle("confirm");
        builder.setMessage(message);
        builder.setPositiveButton(android.R.string.ok,
                new Dialog.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        result.confirm();
                    }
                });
        builder.setNegativeButton(android.R.string.cancel,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        result.cancel();
                    }
                });
        builder.setCancelable(false);
        builder.create();
        builder.show();
        return true;
    }

    @Override
    //设置网页加载的进度条
    public void onProgressChanged(WebView view, int newProgress) {
        super.onProgressChanged(view, newProgress);
    }

    //设置应用程序的标题title
    public void onReceivedTitle(WebView view, String title) {
        super.onReceivedTitle(view, title);
//        mActivity.setTitle(title);
    }

    public void onExceededDatabaseQuota(String url,
                                        String databaseIdentifier, long currentQuota,
                                        long estimatedSize, long totalUsedQuota,
                                        WebStorage.QuotaUpdater quotaUpdater) {
        quotaUpdater.updateQuota(estimatedSize * 2);
    }

    public void onGeolocationPermissionsShowPrompt(String origin,
                                                   GeolocationPermissions.Callback callback) {
        callback.invoke(origin, true, false);
        super.onGeolocationPermissionsShowPrompt(origin, callback);
    }

    public void onReachedMaxAppCacheSize(long spaceNeeded,
                                         long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
        quotaUpdater.updateQuota(spaceNeeded * 2);
    }

    //For Android 3.0+
    @Keep
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
        Log.e("vivi", "  openFileChooserCallBack ");
        mUploadMsg = uploadMsg;
        Intent i = new Intent(
                Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        i.setType("image/*");
        mFragment.startActivityForResult(i, REQUEST_CODE_PICK_IMAGE);
    }

    // For Android < 3.0
    @Keep
    public void openFileChooser(ValueCallback<Uri> uploadMsg) {
        openFileChooser(uploadMsg, "");
    }

    // For Android  > 4.1.1
    @Keep
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
        openFileChooser(uploadMsg, acceptType);
    }

    @Keep
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public boolean onShowFileChooser(WebView mWebView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {

        Log.e("vivi", "  openFileChooserCallBackLollipoPlus ");
        if (mUploadMsgLollipopPlus != null) {
            mUploadMsgLollipopPlus.onReceiveValue(null);
        }
        mUploadMsgLollipopPlus = filePathCallback;

        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(mFragment.getContext().getPackageManager()) != null) {
            // Create the File where the photo should go
            File photoFile = null;
            try {
                photoFile = createImageFile();
                takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
            } catch (IOException ex) {
                // Error occurred while creating the File
                Log.e("CommonWebCHromeClient", "onShowFileChooser: Unable to create Image File", ex);
            }

            // Continue only if the File was successfully created
            if (photoFile != null) {
                mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                        Uri.fromFile(photoFile));
            } else {
                takePictureIntent = null;
            }
        }

        Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
        contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
        contentSelectionIntent.setType("image/*");

        Intent[] intentArray;
        if (takePictureIntent != null) {
            intentArray = new Intent[]{takePictureIntent};
        } else {
            intentArray = new Intent[0];
        }

        Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
        chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
        chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
        mFragment.startActivityForResult(chooserIntent, REQUEST_CODE_PICK_IMAGE_LOLLIPO_PLUS);
        return true;
    }


    private File createImageFile() throws IOException {
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES);
        File imageFile = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );
        return imageFile;
    }

    public static final int REQUEST_CODE_PICK_IMAGE = 0;
    public static final int REQUEST_CODE_PICK_IMAGE_LOLLIPO_PLUS = 1;

    /**
     * 包含这个对象的Fragment，请在onActivityResult方法里调用这个方法
     * Activity就不要考虑了，设计上ChromeClient只和Fragment绑定
     *
     * @param requestCode
     * @param resultCode
     * @param dataIntent
     */
    public void onActivityResult(int requestCode, int resultCode, Intent dataIntent) {
        // 针对web端打开本地文件选择功能
        if (requestCode == REQUEST_CODE_PICK_IMAGE) {
            if (null == mUploadMsg) {
                return;
            }
            Uri receiveUri = getReceiveValue(resultCode, dataIntent);
            mUploadMsg.onReceiveValue(receiveUri);

        } else if (requestCode == REQUEST_CODE_PICK_IMAGE_LOLLIPO_PLUS) {
            if (null == mUploadMsgLollipopPlus) {
                return;
            }

            Uri[] results = null;

            // Check that the response is a good one
            if (resultCode == Activity.RESULT_OK) {
                if (dataIntent == null) {
                    // If there is not data, then we may have taken a photo
                    if (mCameraPhotoPath != null) {
                        results = new Uri[]{Uri.parse(mCameraPhotoPath)};
                    }
                } else {
                    String dataString = dataIntent.getDataString();
                    if (dataString != null) {
                        results = new Uri[]{Uri.parse(dataString)};
                    }
                }
            }

            mUploadMsgLollipopPlus.onReceiveValue(results);
            mUploadMsgLollipopPlus = null;
        }
        Log.e("vivi", "share actviity request code == " + requestCode);
    }


    Uri getReceiveValue(int resultCode, Intent dataIntent) {
        if (resultCode != Activity.RESULT_OK || dataIntent == null) {//不加这段代码的话，第一次若取消第二次会报错
            return null;
        }

        Uri result = dataIntent.getData(); // get file
        if (result == null) {
            return null;
        }

        String fPath = getPath(result);
        // we actually don't allow http links in gallery like google+ or
        // facebook images
        File file = new File(fPath);
        if (!file.exists()) {
            Toast.makeText(mFragment.getContext(),
                    "Please select a local Imagefile.", Toast.LENGTH_LONG)
                    .show();
            return null;
        }

        // Resize+
        Bitmap bitmap = BitmapFactory.decodeFile(fPath);

        if (bitmap == null) {
            return null;
        }

        int newWidth = 200;
        int newHeight = 200;
        Bitmap scaledBitmap = Bitmap.createBitmap(newWidth, newHeight,
                Bitmap.Config.ARGB_8888);

        float ratioX = newWidth / (float) bitmap.getWidth();
        float ratioY = newHeight / (float) bitmap.getHeight();
        float middleX = newWidth / 2.0f;
        float middleY = newHeight / 2.0f;

        Matrix scaleMatrix = new Matrix();
        scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);

        Canvas canvas = new Canvas(scaledBitmap);
        canvas.setMatrix(scaleMatrix);
        canvas.drawBitmap(bitmap, middleX - bitmap.getWidth() / 2, middleY
                - bitmap.getHeight() / 2, new Paint(
                Paint.FILTER_BITMAP_FLAG));

        String resizedFileName = "ImageResized.png";
        File sdCard = Environment.getExternalStorageDirectory();
        File dir = new File(sdCard.getAbsolutePath());
        File filedir = new File(dir, resizedFileName);

        try {
            FileOutputStream fos = new FileOutputStream(filedir);
            scaledBitmap.compress(Bitmap.CompressFormat.PNG, 70, fos);
            fos.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return getImageContentUri(mFragment.getContext(), filedir);
    }

    public String getPath(Uri uri) {
        String[] projection = {MediaStore.Images.Media.DATA};
        Cursor cursor = mFragment.getActivity().managedQuery(uri, projection, null, null, null);
        if (null == cursor) {
            return "";
        }

        int column_index = cursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }

    public static Uri getImageContentUri(Context context, File imageFile) {
        String filePath = imageFile.getAbsolutePath();
        Cursor cursor = context.getContentResolver().query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                new String[]{MediaStore.Images.Media._ID},
                MediaStore.Images.Media.DATA + "=? ",
                new String[]{filePath}, null);
        if (cursor != null && cursor.moveToFirst()) {
            int id = cursor.getInt(cursor
                    .getColumnIndex(MediaStore.MediaColumns._ID));
            Uri baseUri = Uri.parse("content://media/external/images/media");
            cursor.close();
            return Uri.withAppendedPath(baseUri, "" + id);
        } else {
            if (imageFile.exists()) {
                ContentValues values = new ContentValues();
                values.put(MediaStore.Images.Media.DATA, filePath);
                return context.getContentResolver().insert(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            } else {
                return null;
            }
        }
    }

    Context getContext() {
        return mFragment.getContext();
    }

}
